package com.yxhl.zoume.core.func.passenger.ui;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;

import com.afollestad.materialdialogs.MaterialDialog;
import com.yxhl.zoume.R;
import com.yxhl.zoume.account.event.UserAbortLoginEvent;
import com.yxhl.zoume.account.event.UserLoginEvent;
import com.yxhl.zoume.common.ui.custom.RevealLayout;
import com.yxhl.zoume.common.ui.event.AddPassengerEvent;
import com.yxhl.zoume.common.ui.fragment.BaseFragment;
import com.yxhl.zoume.core.func.passenger.event.RenderSelectedPsgersEvent;
import com.yxhl.zoume.core.func.passenger.event.RenderSelectedTakerEvent;
import com.yxhl.zoume.core.func.passenger.event.SelectPsgerEvent;
import com.yxhl.zoume.core.func.passenger.event.SelectTakerEvent;
import com.yxhl.zoume.core.func.passenger.presenter.SelectPsgersPresenter;
import com.yxhl.zoume.core.func.passenger.view.SelectPassengersView;
import com.yxhl.zoume.data.http.model.passenger.ZMPassenger;
import com.yxhl.zoume.data.rxbus.RxBus;
import com.yxhl.zoume.di.component.usercenter.PassengerComponent;
import com.yxhl.zoume.utils.CollectionUtils;
import com.yxhl.zoume.utils.LOG;
import com.yxhl.zoume.utils.PromptUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.OnClick;
import rx.functions.Action1;

import static com.yxhl.zoume.core.func.passenger.ui.MultipleSelectType.ZOU_ME_BUS_ORDER_MULTI_SELECT;
import static com.yxhl.zoume.core.func.passenger.ui.PsgerItemType.SINGLE_SELECT;

/**
 * 选择乘车人
 * by Xboy
 */
public class SelectPsgersFragment extends BaseFragment implements SelectPassengersView {

    private static final String TAG = "SelectPsgersFrag";

    private static final String KEY_TAG = "SelectPsgersFrag";

    private static final String KEY_SELECTED_PASSENGERS = "KEY_SELECTED_PASSENGERS";
    private static final String KEY_ITEM_TYPE = "ITEM_TYPE";
    private static final String KEY_ITEM_MULTIPLE_SELECT_TYPE = "ITEM_MULTIPLE_SELECT_TYPE";


    // 每单乘客人数上限
    private static final int PASSENGERS_COUNT_LIMIT = 5;

    @BindView(R.id.create_passenger_operation_bar)
    RevealLayout mCreatePsgerOperationBar;
    @BindView(R.id.srl_include_refresh_layout)
    SwipeRefreshLayout mSwipeRefreshLayout;
    @BindView(R.id.recycler_include_recycler_view)
    RecyclerView mPsgersRecyclerView;

    @BindView(R.id.confirm_textview)
    TextView mConfirmTextView;

    // Injector
    PassengerComponent component;

    @Inject
    SelectPsgersPresenter mSelectPsgersPresenter;

    SelectPsgersAdapter mSelectPsgersAdapter;
    PsgerItemType mItemType;

    MultipleSelectType mMultipleSelectType;


    // 用户常用乘客
    List<ZMPassenger> mAllPassengers = new ArrayList<ZMPassenger>();
    // 已选择的乘客
    List<ZMPassenger> mSelectedPassengers = new ArrayList<ZMPassenger>();
    // 选中的取票人,默认为第一个乘客
    ZMPassenger mSelectedTaker;

    MaterialDialog mDialogForWaitingPassengers;

    public static SelectPsgersFragment newInstance(List<ZMPassenger> selectedPassengers, PsgerItemType itemType) {

        SelectPsgersFragment fragment = new SelectPsgersFragment();
        Bundle args = new Bundle();
        args.putSerializable(KEY_SELECTED_PASSENGERS, (Serializable) selectedPassengers);
        args.putSerializable(KEY_ITEM_TYPE, itemType);
        fragment.setArguments(args);
        return fragment;
    }

    public static SelectPsgersFragment newInstance(List<ZMPassenger> selectedPassengers, PsgerItemType itemType, MultipleSelectType selectType) {

        SelectPsgersFragment fragment = new SelectPsgersFragment();
        Bundle args = new Bundle();
        args.putSerializable(KEY_SELECTED_PASSENGERS, (Serializable) selectedPassengers);
        args.putSerializable(KEY_ITEM_TYPE, itemType);
        args.putSerializable(KEY_ITEM_MULTIPLE_SELECT_TYPE, selectType);
        fragment.setArguments(args);
        return fragment;
    }


    private void onRxBusEvent() {
        getSubscription().add(toSubscription(UserAbortLoginEvent.class,
                new Action1<UserAbortLoginEvent>() {
                    @Override
                    public void call(UserAbortLoginEvent userAbortLoginEvent) {
                        getActivity().finish();
                    }
                },
                new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        LOG.e(TAG, "throwable=" + throwable.toString());
                        onRxBusEvent();
                    }
                }
        ));

        getSubscription().add(toSubscription(SelectPsgerEvent.class, new Action1<SelectPsgerEvent>() {
                    @Override
                    public void call(SelectPsgerEvent selectPsgerEvent) {
                        ZMPassenger p = selectPsgerEvent.getPassenger();
                        if (null != p) {

                            /**
                             * 判断是否已经选中
                             */
                            boolean isContainsP = false;
                            for (ZMPassenger sp : mSelectedPassengers) {
                                if (p.getPassengerId().equals(sp.getPassengerId())) {
                                    isContainsP = true;
                                    p = sp;
                                    break;
                                }
                            }


                            if (isContainsP) {
                                mSelectedPassengers.remove(p);
                            } else {
                                if(mMultipleSelectType !=ZOU_ME_BUS_ORDER_MULTI_SELECT) {
                                    if (PASSENGERS_COUNT_LIMIT > mSelectedPassengers.size()) {
                                        mSelectedPassengers.add(p);
                                    } else {
                                        PromptUtils.showLong(component.context(), getString(R.string.hint_passengers_number_limit));
                                        p.setSelected(false);
                                    }
                                }else{
                                    mSelectedPassengers.add(p);
                                }
                            }

                            // 设置确认按钮
                            setupConfirmTextView();
                        }
                    }
                },
                new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        LOG.e(TAG, "throwable=" + throwable.toString());
                        onRxBusEvent();
                    }
                }
        ));

        getSubscription().add(toSubscription(AddPassengerEvent.class,
                new Action1<AddPassengerEvent>() {
                    @Override
                    public void call(AddPassengerEvent addPassengerEvent) {
                        ZMPassenger aNewPassenger = addPassengerEvent.getZmPassenger();
                        mAllPassengers.add(0, aNewPassenger);
                        mSelectPsgersAdapter.notifyDataSetChanged();
                    }
                },
                new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        LOG.e(TAG, "throwable=" + throwable.toString());
                        onRxBusEvent();
                    }
                }
        ));

        getSubscription().add(toSubscription(SelectTakerEvent.class,
                new Action1<SelectTakerEvent>() {
                    @Override
                    public void call(SelectTakerEvent selectTakerEvent) {
                        mSelectedTaker = selectTakerEvent.getTaker();
                    }
                },
                new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        LOG.e(TAG, "throwable=" + throwable.toString());
                        onRxBusEvent();
                    }
                }
        ));

        if (PsgerItemType.MULTI_SELECT == mItemType || PsgerItemType.NORMAL == mItemType) {
            getSubscription().add(toSubscription(UserLoginEvent.class,
                    new Action1<UserLoginEvent>() {
                        @Override
                        public void call(UserLoginEvent userLoginEvent) {
                            fetchAddedPassengers();
                        }
                    },
                    new Action1<Throwable>() {
                        @Override
                        public void call(Throwable throwable) {
                            LOG.e(TAG, "throwable=" + throwable.toString());
                            onRxBusEvent();
                        }
                    }
            ));
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 提取已经添加的乘客
        parseArguments();

        // RxBusEvent处理
        onRxBusEvent();
    }

    private void parseArguments() {
        Bundle args = getArguments();
        if (null != args) {
            mSelectedPassengers = (List<ZMPassenger>) args.getSerializable(KEY_SELECTED_PASSENGERS);
            mItemType = (PsgerItemType) args.getSerializable(KEY_ITEM_TYPE);
            mMultipleSelectType = (MultipleSelectType) args.getSerializable(KEY_ITEM_MULTIPLE_SELECT_TYPE);
            LOG.v(KEY_TAG, mItemType + "");
        }
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        // 隐藏“新增乘车人”
        if (SINGLE_SELECT == mItemType) {
            mCreatePsgerOperationBar.setVisibility(View.GONE);
        }

        // 配置RecyclerView
        setupRecyclerView();
        setupSwipeRefreshLayout();

        // 设置确认按钮
        setupConfirmTextView();

        // 绑定View
        mSelectPsgersPresenter.attachView(this);

        // 展示可选取票人
        showSelectableTakers();

        // 数据
        handleData();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        getSubscription().unsubscribe();
    }

    /**
     * 处理数据
     */
    private void handleData() {
        if (SINGLE_SELECT == mItemType) {// 选择取票人
            if (!CollectionUtils.isEmpty(mSelectedPassengers)) {
                mSelectedTaker = mSelectedPassengers.get(0);
            }
        } else {
            // 请求常用乘客
            fetchAddedPassengers();
        }
    }

    /**
     * 展示可选取票人
     */
    private void showSelectableTakers() {
        if (SINGLE_SELECT == mItemType) {
            if (null == mSelectPsgersAdapter) {
                refreshUI(mSelectedPassengers);
            } else {
                mSelectPsgersAdapter.notifyDataSetChanged();
            }
        }
    }

    /**
     * 设置底部按钮文本
     */
    private void setupConfirmTextView() {
        mConfirmTextView.setEnabled(mSelectedPassengers.size() > 0);
        mConfirmTextView.setText(mConfirmTextView.isEnabled() ? "确 定" : "请选择乘车人");
    }

    /**
     * 配置SwipeRefreshLayout
     */
    private void setupSwipeRefreshLayout() {
        if (SINGLE_SELECT == mItemType) {// 选择取票人不需要刷新
            mSwipeRefreshLayout.setEnabled(false);
            return;
        }

        mSwipeRefreshLayout.setColorSchemeResources(
                R.color.swipe_refresh_blue,
                R.color.swipe_refresh_red,
                R.color.swipe_refresh_orange);
        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                fetchAddedPassengers();
            }
        });
    }

    /**
     * 配置RecyclerView
     */
    private void setupRecyclerView() {
        mPsgersRecyclerView.setLayoutManager(new LinearLayoutManager(component.context()));
    }

    /**
     * 数据请求
     */
    private void fetchAddedPassengers() {
        mSelectPsgersPresenter.getAddedPassengers(1, 50, mSelectedPassengers);
    }

    @Override
    protected void initializeInjector() {
        component = getComponent(PassengerComponent.class);
        component.inject(this);
    }

    @Override
    protected int getLayoutResId() {
        return R.layout.fragment_select_passengers;
    }

    @Override
    protected void setupToolBar() {
        if (getActivity() instanceof SelectPsgersActivity) {

            switch (mItemType) {
                case MULTI_SELECT:
                    ((SelectPsgersActivity) getActivity()).setToolbarTitle(getString(R.string.title_select_passengers));
                    break;
                case SINGLE_SELECT:
                    ((SelectPsgersActivity) getActivity()).setToolbarTitle(getString(R.string.title_select_taker));
                    break;
            }
        }
    }

    @Override
    public void renderAddedPassengers(List<ZMPassenger> addedPassengers) {
        mSwipeRefreshLayout.setRefreshing(false);

        // 更新列表
        mAllPassengers.clear();
        mAllPassengers.addAll(addedPassengers);
        if (CollectionUtils.isEmpty(mSelectedPassengers)) {
            refreshUI(mAllPassengers);
        } else {
            if (null == mSelectPsgersAdapter) {
                refreshUI(mAllPassengers);
            } else {
                mSelectPsgersAdapter.notifyDataSetChanged();
            }
        }
    }

    @Override
    public void waitingForQueryPassengers(boolean isWaiting) {
        if (isWaiting) {
            mDialogForWaitingPassengers = new MaterialDialog.Builder(component.context())
                    .content(R.string.dialog_waiting_processing)
                    .progress(true, 0)
                    .canceledOnTouchOutside(false)
                    .show();
        } else {
            if (null != mDialogForWaitingPassengers) {
                mDialogForWaitingPassengers.dismiss();
            }
        }
    }

    /**
     * 刷新列表
     *
     * @param passengers
     */
    private void refreshUI(List<ZMPassenger> passengers) {
        mSelectPsgersAdapter = new SelectPsgersAdapter(component.context(), passengers, mItemType);
        mPsgersRecyclerView.setAdapter(mSelectPsgersAdapter);
    }

    @OnClick(R.id.create_passenger_operation_bar)
    void onCreatePassengerOperationBarClick() {
        getAppComponent().navigator().navigateToAddPassengerActivity(getActivity());
    }

    @OnClick(R.id.confirm_textview)
    void onConfirmTextViewClick() {
        switch (mItemType) {
            case MULTI_SELECT:
                // 儿童数不能大于成人数
                if (mMultipleSelectType != null) {
                    switch (mMultipleSelectType) {
                        case FIXED_BUS_ORDER_MULTI_SELECT:
                        case ZOU_ME_BUS_ORDER_MULTI_SELECT:
                            if (isAdultCountAndChildCountBalanced()) {
                                RxBus.getInstance().send(new RenderSelectedPsgersEvent(mSelectedPassengers));
                            } else {
                                return;
                            }
                            break;
                        default:
                            RxBus.getInstance().send(new RenderSelectedPsgersEvent(mSelectedPassengers));
                    }
                }
                break;
            case SINGLE_SELECT:
                RxBus.getInstance().send(new RenderSelectedTakerEvent(mSelectedTaker));
                break;
        }

        // 关闭当前页面
        if (getActivity() instanceof SelectPsgersActivity) {
            getActivity().finish();
        }
    }

    /**
     * 计算成人、儿童数
     * 用于判断成人和儿童人数配比是否合理
     */
    private Boolean isAdultCountAndChildCountBalanced() {
        int adultCount = 0;
        int childCount = 0;
        for (ZMPassenger p : mSelectedPassengers) {
            if (ZMPassenger.ADULT == p.getPsgerCategory()) {
                ++adultCount;
            } else {
                ++childCount;
            }
        }

        if (adultCount < childCount) {
            new MaterialDialog.Builder(component.context())
                    .title(R.string.dialog_title_hint)
                    .content(R.string.child_cannot_more_than_adult)
                    .positiveText(R.string.dialog_confirm)
                    .positiveColorRes(R.color.app_primary_blue)
                    .canceledOnTouchOutside(false)
                    .show();

            return false;
        }

        return true;
    }
}
